#include "WorldManager.h"
#include <algorithm>
#include <GL/freeglut.h>

WorldManager::WorldManager():
m_entities(),
m_gameBoard(NULL)
{

}
WorldManager::~WorldManager()
{
	std::vector<Entity *>::iterator it;
	for (it = m_entities.begin(); it < m_entities.end(); it++)
	{
		delete (*it);
	}
	m_entities.clear();
}

void WorldManager::SetGameBoard(GameBoard *gb)
{
	m_gameBoard = gb;
}

bool WorldManager::AddEntity(Entity *ent)
{
	if (NULL == ent)
	{
		return false;
	}

	// TODO: should these be grouped by location?
	m_entities.push_back(ent);
	return true;
}

/**
*	Erases and deletes the entity passed
*/
bool WorldManager::RemoveEntity(Entity *ent)
{
	std::vector<Entity *>::iterator it = std::find(m_entities.begin(), m_entities.end(), ent);
	if (m_entities.end() != it)
	{
		m_entities.erase(it);
		delete ent;
		return true;
	}

	return false;
}

bool WorldManager::Initialize(int argc, char **argv)
{
	return true;
}
	
void WorldManager::Tick()
{
	// should keep animating
}

bool WorldManager::MoveEntity(Entity *ent, MoveDirection dir)
{
	if (NULL == m_gameBoard)
	{
		return false;
	}

	MoveInfo m;
	m_gameBoard->GetMoveInfo(ent, dir, m);
	if (m.IsValid())
	{
		// get any entity that is currently at the position
		// the entity is trying to move to
		Entity *target = getEntityAtPosition(m.GetDesitination());

		if (ent->Move(m))
		{
			// if this tile was consumed
			if (ent->ConsumesUponsEntry())
			{
				m_gameBoard->ConsumeTileForMove(m);
			}
			
			// if there is an entity on the tile we are trying to
			// get to, collide with it
			if (NULL != target)
			{
				ent->Collide(target);
			}
		}
	}

	return false;

}

void WorldManager::Render()
{
	glClear(GL_COLOR_BUFFER_BIT);
	if (NULL != m_gameBoard)
	{
		m_gameBoard->Render();
	}

	renderEntities();

	// flush the GFX pipline (draw!)
	glutSwapBuffers();
}

void WorldManager::renderEntities()
{
	std::vector<Entity *>::iterator it;
	for (it = m_entities.begin(); it != m_entities.end(); it++)
	{
		(*it)->Render();
	}
}

Entity* WorldManager::getEntityAtPosition(const Position &pos)
{
	std::vector<Entity *>::iterator it;
	for (it = m_entities.begin(); it != m_entities.end(); it++)
	{
		const Position entPos = (*it)->GetPosition();
		if (entPos.x == pos.x &&
			entPos.y == pos.y)
		{
			return (*it);
		}
	}

	return NULL;
}